xen x86/64: Fix int80 direct trap. It must check for events and also
authorKeir Fraser <keir@xensource.com>
Fri, 6 Apr 2007 14:07:34 +0000 (15:07 +0100)
committerKeir Fraser <keir@xensource.com>
Fri, 6 Apr 2007 14:07:34 +0000 (15:07 +0100)
disable interrupts before exiting to guest context.

Also sprinkle about some assertions about interrupt-enable status.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/compat/entry.S
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/desc.h
xen/include/asm-x86/x86_32/asm_defns.h
xen/include/asm-x86/x86_64/asm_defns.h

index 5f434af0addbef623d84bbdb6fac7a769c7bcf47..93177eda9ae5aab2e1c6b86a6b2c8869c10d7d58 100644 (file)
@@ -283,6 +283,7 @@ bad_hypercall:
 /* %edx == trap_bounce, %ebx == struct vcpu                       */
 /* %eax,%ecx are clobbered. %gs:%esi contain new UREGS_ss/UREGS_esp. */
 create_bounce_frame:
+        ASSERT_INTERRUPTS_ENABLED
         movl UREGS_eflags+4(%esp),%ecx
         movb UREGS_cs+4(%esp),%cl
         testl $(2|X86_EFLAGS_VM),%ecx
index ec254f7382ea85bb2c917a527029db1a3a9bd26f..3d1864e6325cd0732cddca779d2ef725f74f353b 100644 (file)
@@ -137,6 +137,7 @@ compat_bad_hypercall:
 
 /* %rbx: struct vcpu, interrupts disabled */
 compat_restore_all_guest:
+        ASSERT_INTERRUPTS_DISABLED
         RESTORE_ALL
         addq  $8,%rsp
 .Lft0:  iretq
@@ -188,13 +189,14 @@ ENTRY(compat_post_handle_exception)
 
 ENTRY(compat_int80_direct_trap)
         call  compat_create_bounce_frame
-        jmp   compat_restore_all_guest
+        jmp   compat_test_all_events
 
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
 /*   {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]}                             */
 /* %rdx: trap_bounce, %rbx: struct vcpu                                  */
 /* On return only %rbx is guaranteed non-clobbered.                      */
 compat_create_bounce_frame:
+        ASSERT_INTERRUPTS_ENABLED
         mov   %fs,%edi
         testb $2,UREGS_cs+8(%rsp)
         jz    1f
index c921579e3c8fba94ff36a2aecf2f8c874d49aea9..d5701588d7bb33988d11e4841d74db9391ecf7fd 100644 (file)
@@ -38,6 +38,7 @@ switch_to_kernel:
 
 /* %rbx: struct vcpu, interrupts disabled */
 restore_all_guest:
+        ASSERT_INTERRUPTS_DISABLED
         RESTORE_ALL
         testw $TRAP_syscall,4(%rsp)
         jz    iret_exit_to_guest
@@ -230,7 +231,7 @@ ENTRY(int80_direct_trap)
 
         /* Check that the callback is non-null. */
         leaq  VCPU_int80_bounce(%rbx),%rdx
-        cmp   $0, TRAPBOUNCE_flags(%rdx)
+        cmp   $0,TRAPBOUNCE_flags(%rdx)
         jz    int80_slow_path
 
         movq  VCPU_domain(%rbx),%rax
@@ -238,7 +239,7 @@ ENTRY(int80_direct_trap)
         jnz   compat_int80_direct_trap
 
         call  create_bounce_frame
-        jmp   restore_all_guest
+        jmp   test_all_events
 
 int80_slow_path:
         /* 
@@ -256,6 +257,7 @@ int80_slow_path:
 /* %rdx: trap_bounce, %rbx: struct vcpu                           */
 /* On return only %rbx is guaranteed non-clobbered.                      */
 create_bounce_frame:
+        ASSERT_INTERRUPTS_ENABLED
         testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
         jnz   1f
         /* Push new frame at registered guest-OS stack base. */
index af1429ac564a1daff570c4c13e9b4b51369853f5..662cfa951753d9683ccfe34bd75d339e53442301 100644 (file)
@@ -170,7 +170,8 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs)
            regs->r9,  regs->r10, regs->r11);
     printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
            regs->r12, regs->r13, regs->r14);
-    printk("r15: %016lx\n", regs->r15);
+    printk("r15: %016lx    cs: %016lx    ss: %016lx\n",
+           regs->r15, (long)regs->cs, (long)regs->ss);
     show_stack_overflow(cpu, regs->rsp);
 
     panic("DOUBLE FAULT -- system shutdown\n");
@@ -260,11 +261,14 @@ void __init percpu_traps_init(void)
         idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
         idt_table[TRAP_nmi].a          |= 2UL << 32; /* IST2 */
 
-#ifdef CONFIG_COMPAT
-        /* The hypercall entry vector is only accessible from ring 1. */
+        /*
+         * The 32-on-64 hypercall entry vector is only accessible from ring 1.
+         * Also note that this is a trap gate, not an interrupt gate.
+         */
         _set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall);
+
+        /* Fast trap for int80 (faster than taking the #GP-fixup path). */
         _set_gate(idt_table+0x80, 15, 3, &int80_direct_trap);
-#endif
     }
 
     stack_bottom = (char *)get_stack_bottom();
index 154f76736bbaaaa27a53ec9e2d4730f24d5c9cf9..e3b41643bca02fa601f1886b36203838881e7496 100644 (file)
     ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */        \
      ((sel) == (!IS_COMPAT(d) ?                                         \
                 FLAT_KERNEL_CS :                /* Xen default seg? */  \
-                FLAT_COMPAT_KERNEL_CS)) ||      /* Xen default compat seg? */  \
+                FLAT_COMPAT_KERNEL_CS)) ||                              \
      ((sel) & 4))                               /* LDT seg? */
 
 #endif /* __ASSEMBLY__ */
index a972dd10dc7a151b6b532755bca0a20cff96d8e0..b37f3c5a9b1d34088aed2da94dd10040bb5de110 100644 (file)
@@ -8,10 +8,20 @@
 #define SETUP_EXCEPTION_FRAME_POINTER           \
         movl  %esp,%ebp;                        \
         notl  %ebp
+#define ASSERT_INTERRUPT_STATUS(x)              \
+        pushf;                                  \
+        testb $X86_EFLAGS_IF>>8,1(%esp);        \
+        j##x  1f;                               \
+        ud2a;                                   \
+1:      addl  $4,%esp;
 #else
 #define SETUP_EXCEPTION_FRAME_POINTER
+#define ASSERT_INTERRUPT_STATUS(x)
 #endif
 
+#define ASSERT_INTERRUPTS_ENABLED  ASSERT_INTERRUPT_STATUS(nz)
+#define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
+
 #define __SAVE_ALL_PRE                                  \
         cld;                                            \
         pushl %eax;                                     \
index f84cb516aca52759bf450b06c2db47d670753110..231f3aa02ec5374b7155830031c39d4d587112c4 100644 (file)
@@ -8,10 +8,20 @@
 #define SETUP_EXCEPTION_FRAME_POINTER           \
         movq  %rsp,%rbp;                        \
         notq  %rbp
+#define ASSERT_INTERRUPT_STATUS(x)              \
+        pushf;                                  \
+        testb $X86_EFLAGS_IF>>8,1(%rsp);        \
+        j##x  1f;                               \
+        ud2a;                                   \
+1:      addq  $8,%rsp;
 #else
 #define SETUP_EXCEPTION_FRAME_POINTER
+#define ASSERT_INTERRUPT_STATUS(x)
 #endif
 
+#define ASSERT_INTERRUPTS_ENABLED  ASSERT_INTERRUPT_STATUS(nz)
+#define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
+
 #define SAVE_ALL                                \
         cld;                                    \
         pushq %rdi;                             \